/******************************************************************************
 * @ CompanyName : Copyright (C), 2031,  xx Information Technology Co., Ltd.
 * @ FileName    : event_schedule_manage.H
 * @ Descripttion: event and schedule manage
 * @ version     : 1.4
 * @ Author      : SunXin
 * @ Date        : 2023-06-05 11:39:26
 * @ LastEditTime: 2023-06-28 18:20:56
 * @ Chargelog   : 1.xxx
 ******************************************************************************/
//file declaration：Apply the event and Schedule scheduler implementation headers
#ifndef __EVENT_SCHEDULE_MANAGE_H__
#define __EVENT_SCHEDULE_MANAGE_H__

#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */

/***********************************************************************************/
//                  header file           
/***********************************************************************************/
// system includes
#include "event_schedule_config.h"




/***********************************************************************************/
//                  CONFIG MACRO DEF           
/***********************************************************************************/
//LOG DEBUG define in log_print_config.h
//#define LOG_EVENT_SCHEDULE_MANAGE_ENABLExx

//dont repeat define from event_schedule_config.h
//event queue max num def
//#define ES_EVENT_QUEUE_MAX_NUM 15
//schedule queue max num def
//#define ES_SCHEDULE_QUEUE_MAX_NUM 10
//create event:Maximum number of requests to create event queues
//#define ES_CREATE_EVENT_REQ_QUEUE_MAX_NUM ES_EVENT_QUEUE_MAX_NUM
//del event:Maximum number of requests to delete event queues
//#define ES_DEL_EVENT_REQ_QUEUE_MAX_NUM ES_EVENT_QUEUE_MAX_NUM
//create schedule:Maximum number of request to create schedule queues
//#define ES_CREATE_SCHEDULE_REQ_QUEUE_MAX_NUM ES_SCHEDULE_QUEUE_MAX_NUM
//del schedule:Maximum number of schedule queues to be deleted
//#define ES_DEL_SCHEDULE_REQ_QUEUE_MAX_NUM ES_SCHEDULE_QUEUE_MAX_NUM
//The maximum depth of the message queue
//#define ES_MSG_QUEUE_MAX_NUM 5

/***********************************************************************************/
//                  CORE Generic type declaration           
/***********************************************************************************/
// 枚举类型：优先级
typedef enum 
{
    e_ES_PRIORITY_LOW,                      // priority:low
    e_ES_PRIORITY_MID,                      // priority:mid
    e_ES_PRIORITY_HIGH,                     // priority:high
}ENUM_ES_OP_PRIORITY_TYPE_S;

/***********************************************************************************/
//                  CORE Event Type declaration (Add and subtract)          
/***********************************************************************************/
//event:target class see event_schedule_config.h

// 枚举类型：事件业务 ID
typedef enum 
{
    e_ES_EVENT_OP_SINGLE_RELATIVE_TIME,     // 执行方式：相对时间只执行一次（执行间隔生效,且只有时间间隔,执行后就销毁）
    e_ES_EVENT_OP_LOOP_RELATIVE_TIME,       // 执行方式：相对时间定时循环执行（执行间隔生效,且只有时间间隔）
    e_ES_EVENT_OP_SINGLE_SPEC_TIME,         // 执行方式：绝对时间只执行一次（日期有效开始时间有效，执行后就销毁）
    e_ES_EVENT_OP_LOOP_SPEC_TIME_HOLD_TIME, // 执行方式：绝对时间循环执行（日期有效，开始时间有效，执行间隔有效，有跨天可能）
    e_ES_EVENT_OP_EXTERNAL_TRIGGER,         // 执行方式：自动触发（根据设定的自动判定回调函数触发开始和结束）

    e_ES_EVENT_OP_NONE,                    // non-execution
}ENUM_ES_EVENT_TARGET_OP_S;

// 结构体类型：星期定义
typedef struct
{
    uint8_t m_bnMonday:1;
    uint8_t m_bnTuesday:1;
    uint8_t m_bnWednesday:1;
    uint8_t m_bnThursday:1;
    uint8_t m_bnFriday:1;
    uint8_t m_bnSaturday:1;
    uint8_t m_bnSunday:1;
}STRUCT_ES_EVENT_TARGET_WEEK_PER_S;

// 联合体类型：星期定义
typedef union   
{
    STRUCT_ES_EVENT_TARGET_WEEK_PER_S m_struWeekSet;
    uint8_t m_u8WeekSetValue;
}UNION_ES_EVENT_TARGET_WEEK_S;

// 结构体类型：月份定义
typedef struct   
{
    uint16_t m_bnJanuary:1;
    uint16_t m_bnFebruary:1;
    uint16_t m_bnMarch:1;
    uint16_t m_bnApril:1;
    uint16_t m_bnMay:1;
    uint16_t m_bnJune:1;
    uint16_t m_bnJuly:1;
    uint16_t m_bnAugust:1;
    uint16_t m_bnSeptember:1;
    uint16_t m_bnOctober:1;
    uint16_t m_bnNovember:1;
    uint16_t m_bnDecember:1;
}STRUCT_ES_EVENT_TARGET_MONTH_PER_S;

// 联合体类型：月份定义
typedef union
{
    STRUCT_ES_EVENT_TARGET_MONTH_PER_S m_struMonthSet;
    uint16_t m_u16MonthSetValue;
}UNION_ES_EVENT_TARGET_MONTH_S;

// 结构体类型：目标时间定义
typedef struct
{
    // 相对时间的目标设定
    bool relative_tick_valid;                                 // 执行间隔TICK是否有效 true:有效,false:无效
    uint32_t u32_relative_tick_def;                           // 执行相对间隔时间，单位：TICK

    bool relative_ms_valid;                                   // 执行间隔毫秒是否有效 true:有效,false:无效
    uint32_t u32_relative_ms_def;                             // 执行相对间隔时间，单位：毫秒

    bool relative_sec_valid;                                  // 执行间隔秒是否有效 true:有效,false:无效
    uint32_t u32_relative_sec_def;                            // 执行相对间隔时间，单位：秒
    

    // 绝对时间的目标设定
    bool m_blStartStopSetValid;                             // 起止是否有效 true:有效,false:无效
    uint8_t u8StartH;                                       // 起始小时时间
    uint8_t u8StartM;                                       // 起始分钟时间
    uint8_t u8StartS;                                       // 起始秒时间
    uint8_t u8EndH;                                         // 结束小时时间
    uint8_t u8EndM;                                         // 结束分钟时间
    uint8_t u8EndS;                                         // 结束秒时间

    bool m_blDaySetValid;                                   // 日设置是否有效 true:有效,false:无效（每日）
    uint32_t u32SetDay;                                     // 哪一日执行（bit位指示改天是否被选中）

    bool m_blWeekDaySetValid;                               // 周设置是否有效 true:有效,false:无效（每天）
    UNION_ES_SCHEDULE_TARGET_WEEK_S uni_SetWeekDay;         // 每周周几执行

    bool m_blMonthSetValid;                                 // 月设置是否有效 true:有效,false:无效（每月）
    UNION_ES_SCHEDULE_TARGET_MONTH_S uni_SetMonth;          // 哪几个月执行

    bool m_blYearSetValid;                                  // 年设置是否有效 true:有效,false:无效（每年）
    uint16_t u16SetYear;                                    // 哪一年执行
    
}STRUCT_ES_SCHEDULE_TARGET_TIME_T;

// 枚举类型：目标内容
typedef struct STRUCT_ES_EVENT_TARGET
{
    //Target parameter setting
    bool m_blValid;                         // event target:是否有效,true:有效,false:无效
    bool m_blSwitch;                        // event target:开关 true:开启,false:关闭
    ENUM_ES_EVENT_TARGET_TYPE_S m_enuType;  // event target:class 事件业务 ID
    ENUM_ES_EVENT_TARGET_OP_S m_enuOP;      // event target:执行方式
    STRUCT_ES_SCHEDULE_TARGET_TIME_T m_struSetTime;         // schedule target:执行时间设定

    uint16_t content_len;                   // event target:负载内容
    uint8_t* content_buf;                   // event target:负载长度
    uint8_t* p_item;                        // 事件目标携带的内容 例如： STRUCT_SPORT_OBJ

        //target argument set


    STRUCT_ES_SCHEDULE_TARGET_TIME_T m_struSetTime;         // schedule target:执行时间设定
    uint16_t content_len;                                   // schedule target:负载内容
    uint8_t* content_buf;                                   // schedule target:负载长度
    
    //Goal execution setting
    //proc
    void(*EsEventStartHandle)(struct STRUCT_ES_EVENT_TARGET* pevent);                                                  // API:开始handle
    void(*EsEventRunloopHandle)(struct STRUCT_ES_EVENT_TARGET* pevent);                                                // API:运行中handle
    void(*EsEventMessageProcHandle)(struct STRUCT_ES_EVENT_TARGET*pevent,uint8_t* message_buf,uint32_t message_len);   // API:消息处理handle
    void(*EsEventStopHandle)(struct STRUCT_ES_EVENT_TARGET* pevent);                                                   // API:结束handle
}STRUCT_ES_EVENT_TARGET_T;

//ES:Event execution status type
typedef enum 
{
    e_ES_EVENT_NONE,                                                            // non-task
    e_ES_EVENT_WAIT_START,                                                      // Waiting to start
    e_ES_EVENT_RUNNING,                                                         // in execution
    e_ES_EVENT_WAIT_STOP,                                                       // Waiting for the end
    e_ES_EVENT_ALREADY_OVER,                                                    // already over
}ENUM_ES_EVENT_STATE_S;

//----------------------External, internal operations create and delete cache queues---------------------------
//EVENT:Create a custom event request structure
typedef struct
{
    bool m_blValid;                                                              // 自创建队列是否有必要处理,true:有效,false:无效
    STRUCT_ES_EVENT_TARGET_T m_struNewEvent[ES_CREATE_EVENT_REQ_QUEUE_MAX_NUM];  // 创建新事件target class的副本
    ENUM_ES_OP_PRIORITY_TYPE_S m_enuEventProi[ES_CREATE_EVENT_REQ_QUEUE_MAX_NUM];// 创建新事件优先级的副本
}STRUCT_ES_EVENT_SELF_CREATE_T;

//EVENT:Self destruct event request structure
typedef struct
{
    bool m_blValid;                                                             // 自毁队列是否有必要处理,true:有效,false:无效
    uint16_t m_enuOPNum;                                                        // 自毁event target个数
    ENUM_ES_EVENT_TARGET_TYPE_S m_enuOPType[ES_DEL_EVENT_REQ_QUEUE_MAX_NUM];    // 自毁事件target class
}STRUCT_ES_EVENT_SELF_DEL_T;

//CORE events execute content structures
typedef struct
{
    bool m_blIsEmpty;                                                           // 事件是否为空,true:空的,false:非空
    ENUM_ES_OP_PRIORITY_TYPE_S m_enuPriority;                                   // 优先级
    //info
    STRUCT_ES_EVENT_TARGET_T m_enuTarget;                                       // 目标
    ENUM_ES_EVENT_STATE_S m_enuState;                                           // 状态

    //time
    uint32_t m_u32OpTimeSecCount;                                               // event target执行累计时长，单位秒
    uint32_t m_u32OpNumCount;                                                   // event target执行累计次数，单位次

}ENUM_ES_EVENT_STATE_T;

/***********************************************************************************/
//                  CORE Program Type Declaration (Additions and deletions)            
/***********************************************************************************/
//SCHEDULE:CORE program Target class see event_schedule_config.h

//SCHEDULE:CORE plans how goals are executed
typedef enum 
{

}ENUM_ES_SCHEDULE_TARGET_OP_S;




//SCHEDULE:schedule the target structure
typedef struct STRUCT_ES_SCHEDULE_TARGET
{
    //target argument set
    bool m_blValid;                                         // schedule target:是否有效 true:有效,false:无效
    bool m_blSwitch;                                        // schedule target:开关 true:开启,false:关闭
    ENUM_ES_SCHEDULE_TARGET_TYPE_S m_enuType;               // schedule target:class
    ENUM_ES_SCHEDULE_TARGET_OP_S m_enuOP;                   // schedule target:执行方式
    STRUCT_ES_SCHEDULE_TARGET_TIME_T m_struSetTime;         // schedule target:执行时间设定
    uint16_t content_len;                                   // schedule target:负载内容
    uint8_t* content_buf;                                   // schedule target:负载长度

    ////目标执行设定
    //proc
    void(*EsScheduleWaitHandle)(struct STRUCT_ES_SCHEDULE_TARGET *psch);                                                    // 等待handle
    void(*EsScheduleRunloopHandle)(struct STRUCT_ES_SCHEDULE_TARGET *psch);                                                 // 运行中handle
    void(*EsScheduleMessageProcHandle)(struct STRUCT_ES_SCHEDULE_TARGET*pevent,uint8_t* message_buf,uint32_t message_len);  // 消息处理handle
    void(*EsScheduleStopHandle)(struct STRUCT_ES_SCHEDULE_TARGET *psch);                                                    // 结束handle

    //auto 
    bool(*EsScheduleAutoDecideStartHandle)(void);                                                                           // 自动判定开始handle，true:有效开始,false:无效
    bool(*EsScheduleAutoDecideStopHandle)(void);                                                                            // 自动判定结束handle，true:有效结束,false:无效
}STRUCT_ES_SCHEDULE_TARGET_T;

//SCHEDULE:计划执行状态类型
typedef enum 
{
    e_ES_SCHEDULE_NONE,                             //没有计划
    e_ES_SCHEDULE_WAIT_OP_TIME,                     //等待执行时间
    e_ES_SCHEDULE_RUNNING,                          //执行中
    e_ES_SCHEDULE_INVERT_PAUSE,                     //执行中暂停
    e_ES_SCHEDULE_WAIT_STOP,                        //等待结束
    e_ES_SCHEDULE_ALREADY_OVER,                     //已经结束
}ENUM_ES_SCHEDULE_STATE_S;

//----------------------外部，内部操作的创建和删除缓存队列---------------------------
//SCHEDULE:自创建计划请求结构体
typedef struct
{
    bool m_blValid;                                                                         //自创建队列是否有必要处理,true:有效,false:无效
    STRUCT_ES_SCHEDULE_TARGET_T m_struNewSchedule[ES_CREATE_SCHEDULE_REQ_QUEUE_MAX_NUM];    //创建新计划target class的副本
    ENUM_ES_OP_PRIORITY_TYPE_S m_enuScheduleProi[ES_CREATE_SCHEDULE_REQ_QUEUE_MAX_NUM];     //创建新计划优先级的副本
}STRUCT_ES_SCHEDULE_SELF_CREATE_T;

//SCHEDULE:Auto-delete schedule request structure
typedef struct
{
    bool m_blValid;                                                                         //自毁队列是否有必要处理,true:有效,false:无效
    uint16_t m_enuOPNum;                                                                    //自毁schedule target:个数
    ENUM_ES_SCHEDULE_TARGET_TYPE_S m_enuOPType[ES_DEL_SCHEDULE_REQ_QUEUE_MAX_NUM];          //自毁计划target class
}STRUCT_ES_SCHEDULE_SELF_DEL_T;

//SCHEDULE:CORE event plan execution structure
typedef struct
{
    bool m_blLock;                                              //执行锁，true：锁定 false：不锁定

    //event create / del op
    STRUCT_ES_EVENT_SELF_CREATE_T m_ReqEventCreate;             //事件请求创建
    STRUCT_ES_EVENT_SELF_DEL_T m_ReqEventDel;                   //事件请求删除
    
    //SCHEDULE create / del op
    STRUCT_ES_SCHEDULE_SELF_CREATE_T m_ReqScheduleCreate;       //计划请求创建
    STRUCT_ES_SCHEDULE_SELF_DEL_T m_ReqScheduleDel;             //计划请求删除

    bool(*EsManageOpAddEventHandle)(STRUCT_ES_EVENT_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri);    
    //添加事件handle
    
    bool(*EsManageOpDelEventHandle)(ENUM_ES_EVENT_TARGET_TYPE_S del_type);          
    //删除事件handle
    
    bool(*EsManageOpAddSchHandle)(STRUCT_ES_SCHEDULE_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri);   
    //添加计划handle
    bool(*EsManageOpDelSchHandle)(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);            
    //删除计划handle

    void(*EsManageOpCheckEventHandle)(void);                    //检查事件handle
    void(*EsManageOpCheckSchHandle)(void);                      //检测计划handle
    
}STRUCT_ES_OP_T;



//SCHEDULE:CORE计划执行内容结构体
typedef struct
{
    bool m_blIsEmpty;                                           //该计划是否为空,true:空的,false:非空
    ENUM_ES_OP_PRIORITY_TYPE_S m_enuPriority;                   //优先级
    //info
    STRUCT_ES_SCHEDULE_TARGET_T m_enuTarget;                    //目标
    ENUM_ES_SCHEDULE_STATE_S m_enuState;                        //状态

    //time
    uint32_t m_u32OpTimeSecCount;                               //schedule target:执行累计时长，单位秒
    uint32_t m_u32WaitTimeSecCount;                             //schedule target:等待中的累计时长，单位秒
}ENUM_ES_SCHEDULE_STATE_T;


/***********************************************************************************/
//                  MSG Message type and message queue           
/***********************************************************************************/
//ES:Message classification
typedef enum 
{
    e_ES_MSG_EVENT_TYPE,                                        //事件消息类型
    e_ES_MSG_SCH_TYPE,                                          //计划消息类型
    e_ES_MSG_UNKNOW_TYPE,                                       //未知消息类型
}ENUM_ES_MSG_TYPE_S;

//ES:Message operation request
typedef enum 
{
    e_ES_MSG_NO_PAYLOAD,                                        //无负载
    e_ES_MSG_PAYLOAD_CANT_FREE,                                 //负载无需释放
    e_ES_MSG_PAYLOAD_NEED_FREE,                                 //负载需要释放
}ENUM_ES_MSG_OP_REQ_S;

//ES:Message structure
typedef struct
{
    bool m_blValid;                                             //消息是否有效,true:有效,false:无效
    ENUM_ES_MSG_TYPE_S m_enuMsgType;                            //消息类型
    ENUM_ES_OP_PRIORITY_TYPE_S m_enuMsgPrio;                    //消息的优先级
    union
    {
        ENUM_ES_EVENT_TARGET_TYPE_S m_enuEventType;             //事件target class
        ENUM_ES_SCHEDULE_TARGET_TYPE_S m_enuSchType;            //计划target class
    }msg_obj_type;
    ENUM_ES_MSG_OP_REQ_S m_enuMsgOpReq;                         //消息操作请求类型
    
    uint32_t m_U32PayloadLen;                                   //消息负载的长度
    uint8_t* m_u8PayLoadPbuf;                                   //消息负责指针
}STRUCT_ES_MSG_T;

//ES消息结构体
typedef struct
{
    bool m_blOpLock;                                     //操作锁，true：锁定 false：不锁定
    uint16_t m_u16MsgDataNum;                            //消息队列中的个数
    STRUCT_ES_MSG_T m_struMsgData[ES_MSG_QUEUE_MAX_NUM]; //消息队列

    bool(*EsMsgPushHandle)(STRUCT_ES_MSG_T*msg);         //压入msg handle     
    bool(*EsMsgProcHandle)(void);                        //处理msg handle     
}STRUCT_ES_MSG_OBJ_T;

/***********************************************************************************/
//                  External function declaration           
/***********************************************************************************/
//功能 API 类型定义
typedef struct 
{
    //event
    void(*event_init)(void);                                                  //app task init ,must Call this
    bool(*event_del_block)(ENUM_ES_EVENT_TARGET_TYPE_S del_type);             //same task del one event ,Call this
    bool(*event_del_no_block)(ENUM_ES_EVENT_TARGET_TYPE_S del_type);          //diff task del one event ,Call this
    bool(*event_create)(STRUCT_ES_EVENT_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri);                  //diff task del one event ,Call this
    bool(*event_msg_send)(ENUM_ES_EVENT_TARGET_TYPE_S event_type,uint8_t* message_buf,uint32_t message_len);     //send msg to event ,Call this
    bool(*event_msg_find)(ENUM_ES_EVENT_TARGET_TYPE_S event_type,STRUCT_ES_EVENT_TARGET_T** get_point);          //find one event ,Call this
    void(*event_proc)(void);                                                  //app task loop one second ,must Call this
    
    //schedule
    void(*sch_init)(void);                                                       //app task init ,Call this
    bool(*sch_del_block)(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);             //same task del one sch ,Call this
    bool(*sch_del_no_block)(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);          //diff task del one sch ,Call this
    bool(*sch_create)(STRUCT_ES_SCHEDULE_TARGET_T *p_target,ENUM_ES_OP_PRIORITY_TYPE_S set_pri);                  //diff task del one sch ,Call this
    bool(*sch_msg_send)(ENUM_ES_SCHEDULE_TARGET_TYPE_S sche_type,uint8_t* message_buf,uint32_t message_len);      //send msg to sch ,Call this
    bool(*sch_msg_find)(ENUM_ES_SCHEDULE_TARGET_TYPE_S sch_type,STRUCT_ES_SCHEDULE_TARGET_T** get_point);         //find one sch ,Call this
    
    bool(*sch_set_pause)(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);          //sch need pause,Call this
    bool(*sch_set_resume)(ENUM_ES_SCHEDULE_TARGET_TYPE_S del_type);         //sch need resume,Call this
    void(*sch_proc)(void);                                                  //app task loop one second ,must Call this

    //test part
    void(*debug_print)(void);                                                  //print all es
}STRUCT_EVENT_SCHEDULE_API;


//msg part
#if 0
void EsManageMsgInit(void);
void EsManageMsgExternProc(void);
bool EsManageMsgExternPush(STRUCT_ES_MSG_T*msg);
#endif

/***********************************************************************************/


#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

#endif /* __EVENT_SCHEDULE_MANAGE_H__ */

